package com.mixes.logic;

import static com.mixes.field.FacebookField.*;
import static com.mixes.util.Utility.*;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.LinkedList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;

import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import com.mixes.field.IField;

/**
 * http://takutless.blogspot.jp/2011/03/facebook-android-sdk.html<br>
 * @author Author:
 * @version Revision:
 */
public class FacebookLogic extends ALogic {
    private static FacebookLogic sFacebookLogic;

    private Facebook mFacebook;

    private Activity mActivity;

    private AsyncFacebookRunner mAsyncFacebookRunner;

    private Handler mHandler;

    public FacebookLogic(Activity activity, String appId) {
        mActivity = activity;
        mHandler = new Handler();
        mFacebook = new Facebook(appId);
        mAsyncFacebookRunner = new AsyncFacebookRunner(mFacebook);
    }

    public static FacebookLogic getInstance(Activity activity, String appId) {
        if (sFacebookLogic == null) {
            sFacebookLogic = new FacebookLogic(activity, appId);
        }
        return sFacebookLogic;
    }

    public void authorize(OnAuthorizeListener onAuthorizeListener) {
        mOnAuthorizeListener = onAuthorizeListener;

        if (mOnAuthorizeListener != null) {
            mOnAuthorizeListener.onStart();
        }
        mFacebook.authorize(mActivity, new DialogListener() {
            @Override
            public void onFacebookError(FacebookError e) {
                if (mOnAuthorizeListener != null) {
                    mOnAuthorizeListener.onFailed(e);
                }
            }

            @Override
            public void onError(DialogError e) {
                if (mOnAuthorizeListener != null) {
                    mOnAuthorizeListener.onFailed(new Exception());
                }
            }

            @Override
            public void onComplete(Bundle values) {
                if (mOnAuthorizeListener != null) {
                    mOnAuthorizeListener.onComplete();
                }
            }

            @Override
            public void onCancel() {
                if (mOnAuthorizeListener != null) {
                    mOnAuthorizeListener.onFailed(new Exception());
                }
            }
        });
    }

    public void prepareTimeLine(OnTimeLineListener onTimeLineListener) {
        mOnTimeLineListener = onTimeLineListener;

        if (mOnTimeLineListener != null) {
            mOnTimeLineListener.onStart();
        }
        mAsyncFacebookRunner.request("me/feed", new RequestListener() {
            @Override
            public void onMalformedURLException(MalformedURLException e, Object state) {
                // ネットワークエラー時に呼ばれる
            }

            @Override
            public void onIOException(IOException e, Object state) {
                // 存在しないリソースにアクセスしようとした場合に呼ばれる
            }

            @Override
            public void onFileNotFoundException(FileNotFoundException e, Object state) {
                // リクエストされたURLが無効だった場合に呼ばれる
            }

            @Override
            public void onFacebookError(FacebookError e, Object state) {
                // Facebook側でのエラー発生時に呼ばれる
            }

            @Override
            public void onComplete(String response, Object state) {
                // requestに対してresponseが返された場合に呼ばれる
                final LinkedList<HashMap<IField, Object>> timeLineList = new LinkedList<HashMap<IField, Object>>();

                try {
                    JSONObject jsonObject = new JSONObject(response);
                    JSONArray jsonArray = jsonObject.getJSONArray("data");

                    HashMap<IField, Object> timeLineMap;
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject json = jsonArray.getJSONObject(i);

                        timeLineMap = new HashMap<IField, Object>();
                        if (json.has(description.toString())) {
                            timeLineMap.put(description, json.getString(description.toString()));
                        }
                        // JSONObject applicationObj = json.getJSONObject(application.toString());
                        // JSONObject linkObj = json.getJSONObject(link.toString());
                        // JSONObject captionObj = json.getJSONObject(caption.toString());
                        // JSONObject storyTagObj = json.getJSONObject(story_tags.toString());
                        // JSONObject fromObj = json.getJSONObject(from.toString());
                        // JSONObject typeObj = json.getJSONObject(type.toString());
                        // JSONObject updatedTimeObj = json.getJSONObject(updated_time.toString());
                        // JSONObject pictureObj = json.getJSONObject(picture.toString());
                        // JSONObject idObj = json.getJSONObject(id.toString());
                        // JSONObject storyObj = json.getJSONObject(story.toString());
                        // JSONObject statusTypeObj = json.getJSONObject(status_type.toString());
                        // JSONObject descriptionObj = json.getJSONObject(description.toString());
                        // JSONObject nameObj = json.getJSONObject(name.toString());
                        // JSONObject createdTimeObj = json.getJSONObject(created_time.toString());
                        // JSONObject commentsObj = json.getJSONObject(comments.toString());
                        //
                        // timeLineMap.put(description, json.getString(description.toString()));
                        timeLineList.add(timeLineMap);
                    }
                } catch (final JSONException e) {
                }
                if (!isEmpty(timeLineList)) {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (mOnTimeLineListener != null) {
                                mOnTimeLineListener.onComplete(timeLineList);
                            }
                        }
                    });
                } else {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (mOnTimeLineListener != null) {
                                mOnTimeLineListener.onFailed(new NullPointerException());
                            }
                        }
                    });
                }
            }
        });

    }
}
